Flash Write Protect机制


1. 使用背景

在实际项目使用中,当 Kernel 启动后,很多分区对 Kernel而言,都只是只读分区。但这些分区又可以通过 mtd 设备对分区进行修改或者由于某种不确定因素导致分区被异常修改,常常这类的修改会导致系统没办法启动。所以针对此类场景,新增了Flash Write Protect 的用户接口。


2. 使用方法

  1. Kernel Config 默认没有打开 Write Protect 功能,需要手动打开:

    NOR:CONFIG_SS_FLASH_ISP_WP

    NAND:CONFIG_SS_SPINAND_WP

    注:两个 Config 同一时间只能开一个。

  2. 通过 /sys/class/mstar/msys/ 下的 protect 和 protect_valid 文件的读写实现对Flash Write Protect 的操作:

    获取当前 Flash 可保护的区间信息:

    设定当前保护的区域:

    获取当前保护区域:


3. 配制指南


3.1. 原理描述

Flash 的 Write Protect 功能一般通过设置 Flash的某些寄存器实现,具体的操作方式可以参考 Flash 的 Datasheet。各厂商的 Flash支持的 Write Protect 功能都有一些差异,但基本的保护功能大同小异。

如 W25Q128的 Write  Protect 功能是通过写 Status Register 1 的 bit 6 : bit2 实现:

读写 Status Register 1 的方法:

各bit值对应的保护区域为:

如上图, WPS 为是否使用每个 Block 单独设置 Write Protect 功能,该功能不是所有 Flash 厂商都支持,所以我们的驱动暂时没有支持 WPS = 1 的使用场景。

图中 CMP 为是否支持 Write Protest 功能范围细化,该功能也并不是所有 Flash 厂商都支持,所以我们的驱动也暂时没有支持 CMP = 1 的使用场景。

SPINAND 的原理和 SPINOR 是相同的,仅差 SPINAND 和 SPINOR 读写的寄存器不一样以及发送的命令不一样,如 W25N01G:

读写 Status Register 1 的方法:

各bit值对应的保护区域为:


3.2. 增加驱动支持

SPINOR Flash 需要增加 drivers/sstar/flash_isp/drvDeviceInfo.c 中 _hal_SERFLASH_table 数组的 pWriteProtectTable 成员,该成员为 Write Protect 的保护信息:

_pstWriteProtectTable_W25Q128 则为储存 W25Q128 Flash Write Protect 的信息:

数组的第一列为 Status Register 1 的值, 第二列为值的Mask,第三列为保护范围的低地址,第四列为保护范围的高地址。

SPINAND Flash 需要增加 drivers/sstar/spinand/drv/mdrv_spinand_dev.c 中 _gtSpinandWpTable 的 pWriteProtectTable 成员,该成员为 Write Protect 的保护信息:

_pstWriteProtectTable_W25N01GV 则为储存 W25N01GVFlash Write Protect 的信息:

注意:protect table 的最后一项 u32LowerBound 和 u32UpperBound 一定要为0xFFFFFFFF,这个为数组索引结束的标志。

_hal_SERFLASH_table 和 _gtSpinandWpTable数组的最后一项也是数组索引结束的标志,请不要修改。


3.3. 设置开机保护区域

因为驱动很难知道用户应用希望如何设定保护区域,所以默认保护区域设置在 Alkaid的编译配置中,根据不同分区设置不同的保护区域显得更加合理。

如在 project/image/configs/i2m/spinand.ubifs.p2.partition.wp.config 中增加 FLASH_WP_RANGE 变量: